#pragma once

#include "endpoint.hpp"
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

class Socket
{
public:
    Socket() = default;
    Socket(int fd_) : fd(fd_) {}
    ~Socket() {}

    int GetFd() const { return fd; }
    int Create(int family, int type, int proto)
    {
        if (fd > 0) return fd;
        fd = socket(family, type, proto);
        return fd;
    }
    int Bind(const EndPoint& ep) const
    {
        return bind(fd, ep.GetAddr(), ep.GetAddrLen());
    }
    int Listen(int backlog = 8) const
    {
        return listen(fd, backlog);
    }
    int Accept(struct sockaddr_in& addr) const
    {
        socklen_t size;
        return accept(fd, (struct sockaddr*)&addr, &size);
    }
    int Connect(const EndPoint& peer) const
    {
        return connect(fd, peer.GetAddr(), peer.GetAddrLen());
    }
    int Send(const char* buff, int len) const
    {
        return send(fd, buff, len, 0);
    }
    int Sendto(const EndPoint& peer, char* buff, int len) const
    {
        return sendto(fd, buff, len, 0,peer.GetAddr(), peer.GetAddrLen());
    }
    int Recv(char* buff, int len) const
    {
        return recv(fd, buff, len, 0);
    }
    int Recvfrom(const EndPoint& peer, char* buff, int len) const
    {
        socklen_t size;
        return recvfrom(fd, buff, len, 0, peer.GetAddr(), &size);
    }
    int Close()
    {
        int ret = close(fd);
        fd = -1;
        return ret;
    }
private:
    int fd { -1 };
};